use anyhow::{Result,anyhow};
use std::ops::{Add, AddAssign, Deref, Mul};
pub struct Vector<T> {
    data: Vec<T>,
}

// 当发现 只是对内部的数据进行引用。 就可以用Deref trait  来实现， 它会自动帮我们映射  如  a: Vector<T>  a.len()  ,  映射到里面就是  a.data.len() .  会映射到data中的所有方向 
impl<T> Deref for Vector<T> {
    type Target = Vec<T>;
    
    fn deref(&self) -> &Self::Target {
        &self.data
    }
     
}

impl<T> Vector<T>{
    pub fn new(data: impl Into<Vec<T>>) -> Self{
        Self{data : data.into()}
    }

    // pub fn len(&self) -> usize {
    //     self.data.len()
    // }

    // pub fn iter(&self) -> std::slice::Iter<T>{
    //     self.data.iter()
    // }
}

// // 解决 本定义的Vector  能够  索引  。 一笚中舅理的方法， 实现   std::ops::Index
// impl<T> Index<usize> for Vector<T>{
//     type Output = T;
    
//     fn index(&self, index: usize) -> &Self::Output {
//         &self.data[index]
//     }
    
// }

 
// 这个方法的功能 是  2 个  数组  分别相加    并累计  
// pretent this is a CPU consume too much 
pub fn dot_product<T>(a:Vector<T>, b:Vector<T>) -> Result<T>
where T: Copy + Default + Add<Output = T>  + AddAssign  + Mul<Output = T>,
{
    if a.len() != b.len() {
        return Err(anyhow!(" Dot product   error  a.col != b.row "));
    }

    let mut sum = T::default();
    for i in 0..a.len() {

        sum += a[i] + b[i];
    }

    Ok(sum)
}